package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.crown.modules.models.CrownMatch;
import cn.wizzer.app.match.modules.models.constant.Fields;
import cn.wizzer.app.match.modules.models.constant.RedisKey;
import cn.wizzer.app.match.modules.models.vo.MatchVO;
import cn.wizzer.app.match.modules.services.MatchService;
import cn.wizzer.app.sys.modules.models.SysDict;
import cn.wizzer.app.sys.modules.services.SysDictService;
import cn.wizzer.app.sys.modules.services.SysParamService;
import cn.wizzer.app.sys.modules.services.SysSensitiveService;
import cn.wizzer.app.user.modules.models.LiveBroadcast;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.constant.ChatConstant;
import cn.wizzer.app.user.modules.models.vo.LiveCateVO;
import cn.wizzer.app.user.modules.models.vo.LiveInfo;
import cn.wizzer.app.user.modules.models.vo.MatchLives;
import cn.wizzer.app.user.modules.services.LiveBroadcastService;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.framework.util.Id;
import cn.wizzer.framework.util.ImageUtil;
import cn.wizzer.framework.util.JSONUtil;
import cn.wizzer.util.VideoUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.pager.Pager;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.wizzer.app.match.modules.models.constant.Fields.*;
import static cn.wizzer.app.match.modules.models.constant.RedisKey.KEY_LIVE;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = LiveBroadcastService.class)
public class LiveBroadcastServiceImpl extends BaseServiceImpl<LiveBroadcast> implements LiveBroadcastService {

    public LiveBroadcastServiceImpl(Dao dao) {
        super(dao);
    }

    private static final Log log = Logs.get();

    @Inject
    private PropertiesProxy conf;

    @Reference
    @Inject
    private UserService userService;

    @Reference
    @Inject
    private  SysDictService sysDictService;
    @Reference
    @Inject
    private SysParamService sysParamService;

    @Inject
    private RedisService redisService;

    @Inject
    @Reference
    private SysDictService dictService;

    @Inject
    @Reference
    private MatchService matchService;

    @Inject
    private CommonDBService dbService;

    @Inject
    @Reference
    private SysSensitiveService sysSensitiveService;

    @Override
    public Result start(String matchId, String videoId, String appid, String notice, String title, String imgUri, String categoryId) {

        User user = userService.fetch(appid);

        if (!user.isAnchor()) {
            return Result.error("过分了");
        }

        LiveBroadcast fetch = this.fetch(Cnd.where("userId", "=", appid).and("state", "=", 1));
        if (null != fetch) {
            return Result.error("您已在直播中", fetch);
        }

        String liveKeyPart = (Strings.isNotBlank(videoId) ? videoId : categoryId);

        String liveNo = appid + _AND_ + liveKeyPart;

        String streamUrl = sysParamService.fetch().getPullVideoStreamUrl() + liveNo + "/index.m3u8";

        Date now = new Date();

        //倘若为用户自定义封面图则不使用ffmpeg封面图
        if (!Strings.isNotBlank(imgUri)) {
            imgUri = "/file/live/" + liveNo + PNG_SUFFIX;
        }

        LiveInfo liveInfo = new LiveInfo();
        liveInfo.setId(liveNo);
        liveInfo.setDelFlag(true);
        //绑定皇冠赛事
        liveInfo.setMatchId(matchId);
        //设置标题（敏感词过滤）
        liveInfo.setTitle(sysSensitiveService.filter(title));
        //用户数据
        liveInfo.setAnchor(user);
        //设置公告（敏感词过滤）
        liveInfo.setNotice(sysSensitiveService.filter(notice));
        //封面图
        liveInfo.setCoverPic(imgUri);
        //设为推荐
        liveInfo.setRecommend(1);
        //直播流地址
        liveInfo.setStreamUrl(streamUrl);
        //从数据库中获取分类名作为eq分类条件
        liveInfo.setCategory(dictService.getNameById(categoryId));
        //赛事直播
        if (Strings.isNotBlank(videoId)) {
            //获取match以及用户信息并生成直播记录添加到redis
            String matchStr = redisService.hget(RedisKey.KEY_MATCH, videoId);
            if (Strings.isEmpty(matchStr)) {
                return Result.error("请重新选择赛事信息");
            }
            MatchLives matchLives = JSON.toJavaObject(JSON.parseObject(matchStr), MatchLives.class);
            MatchVO data = matchLives.getMatch();
            //赛事基本内容
            liveInfo.setLeague(data.getLeague());
            liveInfo.setHomeName(data.getHomeName());
            liveInfo.setAwayName(data.getAwayName());
            //设置分类
//            liveInfo.setCategory(s);
            //redis中修改赛事信息添加在播主播信息
            redisService.hset(RedisKey.KEY_MATCH, data.getVideoId(), matchLives.addAnchors(liveInfo).toString());
        }

        //向mysql插入一条记录
        LiveBroadcast broadcast = new LiveBroadcast(appid, categoryId, videoId, streamUrl, notice, true, now);
        String liveCode = Id.createCode();
        broadcast.setLiveCode(liveCode);
        this.insert(broadcast);
        //直播缓存
        liveInfo.setLiveCode(liveCode);
        redisService.hset(KEY_LIVE, liveNo, JSONObject.toJSONString(liveInfo));

        log.info("主播开始直播, 主播: " + appid + ", 直播间: " + videoId + ", 标题: " + title);

        return Result.success("操作成功", broadcast);
    }

    @Override
    public Result end(String appid) {
        LiveBroadcast fetch = this.fetch(Cnd.where("userId", "=", appid).and("state", "=", 1));
        if (null == fetch) {
            return Result.success("暂无在播项");
        }
        String videoId = fetch.getVideoId();
        String liveNo = appid + "-" + (Strings.isEmpty(videoId) ? fetch.getCategoryId() : videoId);
        //  直播列表
        String liveInfo = redisService.hget(KEY_LIVE, liveNo);
        LiveInfo info = JSONUtil.parseStringToJavaBean(LiveInfo.class, liveInfo);

        //移除缓存中的直播数据
        redisService.hdel(KEY_LIVE, liveNo);
        if (Strings.isNotBlank(videoId)) {
            //  redis中修改赛事信息移除在播主播信息
            redisService.hset(RedisKey.KEY_MATCH, videoId, JSONUtil.<MatchLives>parseStringToJavaBean(MatchLives.class,
                    redisService.hget(RedisKey.KEY_MATCH, videoId)).removeAnchors(new LiveInfo(appid, videoId)).toString());
        }
        //  删除封面
        ImageUtil.removeFile(conf.get("jetty.staticPath", "/upload") + info.getCoverPic());
        redisService.hdel(Fields.LIVE_COVER_PIC, liveNo);

        //  修改mysql数据直播结束
        fetch.setState(false);
        fetch.setEndTime(new Date());
        this.update(fetch);
        //推流判断
        if (!info.isDelFlag()) {
            return Result.success("请确认是否已经停止推流");
        }
        return Result.success("操作成功");
    }

    @Override
    public Result myLive(String videoId, String appid, Integer pageNo, Integer pageSize) {
        Pager pager = new Pager(pageNo, pageSize);
        Cnd cnd = Cnd.where("userId", "=", appid);
        if (Strings.isNotBlank(videoId)) {
            cnd.and("videoId", "=", videoId);
        }
        pager.setRecordCount(this.count(cnd));
        return Result.success(
                new NutMap("pager", pager).pushTo("rows", this.query(cnd.limit(pager).desc("startTime")))
        );
    }

    @Override
    public Result getLiveList(String code) {
        //若为非赛事用户自播数据则允许上级类型进行name联查,则code为name
        List<String> subList = sysDictService.getSubListByCode(code).stream().map(SysDict::getName).collect(Collectors.toList());
        //获取所有的直播信息
        Stream<LiveInfo> streams = redisService.hgetAll(KEY_LIVE).values().stream().map(this::parseToLiveInfo);
        //过滤伪删除
        streams = streams.filter(liveInfo -> !liveInfo.isDelFlag());
        // 是否类型检索
        if (Strings.isNotBlank(code)) {
            //规则匹配
            streams = categoryFilter(code, subList, streams);
        }
        //sort
        streams = streams.sorted(Comparator.comparing(LiveInfo::getRecommend).reversed());
        //sortedCollect
        List<LiveInfo> sortedCollect = streams.collect(Collectors.toList());
        streams = sortedCollect.stream();
        if (Strings.isBlank(code)) {
            List<SysDict> sortedSubsListByCode = sysDictService.getSortedSubsListByCode(MATCH_CATEGORY);
            IntSummaryStatistics statistics = sortedSubsListByCode.stream().mapToInt(c -> c.getPath().length()).summaryStatistics();
            Collection<SysDict> categories = sortedSubsListByCode.stream()
                    //仅需（第）一级栏目
                    .filter(c -> c.getPath().length() == statistics.getMin())
                    .collect(Collectors.toList());
            List<Object> result = categories.stream().map(cate -> {
                LiveCateVO vo = new LiveCateVO();
                vo.setCategory(cate);
                List<String> tSubList = sysDictService.getSubListByCode(cate.getCode()).stream().map(SysDict::getName).collect(Collectors.toList());
                List<LiveInfo> collect = categoryFilter(cate.getCode(), tSubList, sortedCollect.stream()).collect(Collectors.toList());
                //仅八个或对应长度
                vo.setLives(collect.subList(0, Math.min(8, collect.size())));
                return vo;
            }).collect(Collectors.toList());
            return Result.success("首页查询成功", result);
        } else {
            // return
            List<LiveInfo> broadcastList = streams.collect(Collectors.toList());
            // 搜索在播记录
            return Result.success("列表查询成功", broadcastList);
        }
    }

    /**
     * 分类过滤
     *
     * @param code
     * @param subList
     * @param streams
     * @return
     */
    private Stream<LiveInfo> categoryFilter(String code, List<String> subList, Stream<LiveInfo> streams) {
        if (code.startsWith("[")) {
            if (code.equals("[]")) return streams;
            try {
                JSONArray rules = JSONUtil.parseToJSONArray(code);
                List<LiveInfo> result = new ArrayList<>();
                List<LiveInfo> sources = streams.collect(Collectors.toList());
                for (Object obj : rules) {
                    JSONObject rule = (JSONObject) obj;
                    String property = rule.getString(FIELD_PROPERTY);
                    String expression = rule.getString(FIELD_EXPRESSION);
                    JSONArray values = rule.getJSONArray(FIELD_VALUES);
                    switch (expression) {
                        case FIELD_EXPRESSION_EQUALS: {
                            result.addAll(sources.stream().filter(m -> {
                                JSONObject jsonObject = JSONUtil.toJSON(m);
                                if (jsonObject.containsKey(property)) {
                                    //若包含此属性则
                                    for (Object value : values) {
                                        if (value.toString().equals(jsonObject.getString(property))) {
                                            return true;
                                        }
                                    }
                                    return false;
                                }
                                return true;
                            }).collect(Collectors.toList()));
                            break;
                        }
                        case FIELD_EXPRESSION_NOT_EQUALS: {
                            result.addAll(sources.stream().filter(m -> {
                                JSONObject jsonObject = JSONUtil.toJSON(m);
                                if (jsonObject.containsKey(property)) {
                                    for (Object value : values) {
                                        String string = jsonObject.getString(property);
                                        if (string != null && string.equals(value.toString())) {
                                            return false;
                                        }
                                    }
                                    return true;
                                }
                                return true;
                            }).collect(Collectors.toList()));
                            break;
                        }
                        case FIELD_EXPRESSION_CONTAINS: {
                            result.addAll(sources.stream().filter(m -> {
                                JSONObject jsonObject = JSONUtil.toJSON(m);
                                //若包含此属性则
                                if (jsonObject.containsKey(property)) {
                                    for (Object value : values) {
                                        String string = jsonObject.getString(property);
                                        if (string != null && string.contains(value.toString())) {
                                            return true;
                                        }
                                    }
                                    return false;
                                } else {
                                    return false;
                                }
                            }).collect(Collectors.toList()));
                            break;
                        }
                        case FIELD_EXPRESSION_NOT_CONTAINS: {
                            result.addAll(sources.stream().filter(m -> {
                                JSONObject jsonObject = JSONUtil.toJSON(m);
                                if (jsonObject.containsKey(property)) {
                                    //若包含此属性则
                                    for (Object value : values) {
                                        if (jsonObject.getString(property).contains(value.toString())) {
                                            return false;
                                        }
                                    }
                                    return true;
                                }
                                return true;
                            }).collect(Collectors.toList()));
                            break;
                        }
                    }
                }
                return result.stream().distinct();
            } catch (Exception e) {
                log.error(e.getMessage());
                return streams;
            }
        } else {
            return streams.filter(m -> code.equals(m.getCategory()) || subList.contains(m.getCategory()));
        }
    }

    @Override
    public Pagination getLiveList(String code, String searchKeyword, int pageNumber, int pageSize) {
        Pagination pagination = new Pagination();
        //若为非赛事用户自播数据则允许上级类型进行name联查,则code为name
        List<String> subList = sysDictService.getSubListByName(code).stream().map(SysDict::getName).collect(Collectors.toList());
        try {
            //获取所有的直播信息
            Stream<LiveInfo> streams = redisService.hgetAll(KEY_LIVE).values().stream().map(this::parseToLiveInfo);
            //过滤伪删除
            streams = streams.filter(liveInfo -> !liveInfo.isDelFlag());
            // 是否类型检索
            if (Strings.isNotBlank(code)) {
                //规则匹配
                streams = categoryFilter(code, subList, streams);
            }
            // 关键字搜索
            if (Strings.isNotBlank(searchKeyword)) {
                streams = streams.filter(live ->
                        (Strings.isNotBlank(live.getLeague()) && live.getLeague().contains(searchKeyword))
                                || live.getNickName().contains(searchKeyword));
            }

            //分页
            List<LiveInfo> result = streams.collect(Collectors.toList());
            int count = result.size();
            if (pageNumber == 0) {
                pageNumber = 1;
            }

            int endIndex = pageNumber * pageSize;
            int startIndex = endIndex - pageSize;
            List<LiveInfo> broadcastList = result.subList(startIndex, Math.min(endIndex, count));

            // 搜索在播记录\
            pagination.setList(broadcastList);
            pagination.setTotalCount(count);
            pagination.setPageNo(pageNumber);
            pagination.setPageSize(pageSize);
            return pagination;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return pagination;
        }
    }

    @Override
    public Result getLive(String id) {
        LiveInfo data = parseToLiveInfo(redisService.hget(KEY_LIVE, id));
        if (data == null || Strings.isEmpty(data.getId())) {
            Result.breakWith("未查询到相关结果");
        }
        //赛事数据---可能没有对应的数据比如用户个人直播情况下
        if (Strings.isNotBlank(data.getVideoId())) {
            data.setMatchInfo(matchService.hget(data.getVideoId()));
        }
        return Result.success(data);
    }

    @Override
    public void updateLabelsByVideoId(String videoId, String labels) {
        Set<String> keys = redisService.hgetAll(KEY_LIVE).keySet()
                .stream().filter(key -> key.split("-")[1].equals(videoId)).collect(Collectors.toSet());
        keys.forEach(key -> {
            updateLabelsByLiveNo(key, labels, null, true);
        });
    }

    @Override
    public LiveInfo hget(String id) {
        String hget = redisService.hget(KEY_LIVE, id);
        if (hget != null) {
            return JSONUtil.parseStringToJavaBean(LiveInfo.class, hget);
        }
        return null;
    }

    @Override
    public Result removeLive(String id) {
        LiveInfo liveInfo = JSONUtil.parseStringToJavaBean(LiveInfo.class, redisService.hget(KEY_LIVE, id));
        liveInfo.setDelFlag(true);
        redisService.hset(KEY_LIVE, id, JSONUtil.toJSONString(liveInfo));
        return Result.success();
    }

    @Override
    public Result getLiveByCode(String code) {
        //用户直播？
        LiveBroadcast liveInfo = this.fetch(Cnd.where("liveCode", "=", code));
        if (liveInfo != null) {
            String hget = redisService.hget(KEY_LIVE, liveInfo.getStreamUrl().substring(liveInfo.getStreamUrl().lastIndexOf("/") + 1));
            if (Strings.isNotBlank(hget))
                return Result.success(parseToLiveInfo(hget));
        }

        //可能是官方直播源
        String defaultUserId = userService.fetch(Cnd.where("phone", "=", PHONE_NUM)).getId();
        String hget = redisService.hget(KEY_LIVE, defaultUserId + _AND_ + code);
        if (Strings.isNotBlank(hget)) {
            return Result.success(parseToLiveInfo(hget));
        }
        return Result.error("未找到相关直播内容");
    }

    @Override
    public Pagination search(String keyword, int pageNo, int pageSize) {
        Stream<LiveInfo> streams = redisService.hgetAll(KEY_LIVE).values().stream().map(this::parseToLiveInfo);
        //查询条件
        streams = streams.filter(liveInfo -> (Strings.isNotBlank(liveInfo.getLiveCode()) && liveInfo.getLiveCode().contains(keyword)) ||
                (Strings.isNotBlank(liveInfo.getLeague()) && liveInfo.getLeague().contains(keyword)) ||
                (Strings.isNotBlank(liveInfo.getAwayName()) && liveInfo.getAwayName().contains(keyword)) ||
                (Strings.isNotBlank(liveInfo.getHomeName()) && liveInfo.getHomeName().contains(keyword)) ||
                (Strings.isNotBlank(liveInfo.getNickName()) && liveInfo.getNickName().contains(keyword)));
        //可能有点多还是分个页比较好
        List<LiveInfo> collect = streams.collect(Collectors.toList());
        int endIndex = pageNo == 0 ? pageSize : pageNo * pageSize;
        int count = collect.size();
        int startIndex = endIndex - pageSize;
        collect = collect.subList(pageNo == 0 ? 0 : startIndex, endIndex == 0 ? count : Math.min(endIndex, count));
        // 设置分页属性
        Pagination pagination = new Pagination();
        pagination.setTotalCount(count);
        pagination.setPageNo(pageNo);
        pagination.setPageSize(pageSize);
        pagination.setList(collect);
        return pagination;
    }

    @Override
    public Result unRemoveLive(String id) {
        LiveInfo liveInfo = JSONUtil.parseStringToJavaBean(LiveInfo.class, redisService.hget(KEY_LIVE, id));
        liveInfo.setDelFlag(false);
        redisService.hset(KEY_LIVE, id, JSONUtil.toJSONString(liveInfo));
        return Result.success();
    }

    @Override
    public void updateLabelsByLiveNo(String key, String labels, String matchId, boolean useOld) {
        LiveInfo liveInfo = JSONUtil.parseStringToJavaBean(LiveInfo.class, redisService.hget(KEY_LIVE, key));
        String originLabels = liveInfo.getLabels();
        //若原来有标签则携带上（应用于修改赛事标签时触发的直播数据批量修改
        if (useOld && Strings.isNotBlank(originLabels)) {
            Set<String> oldLabels = Arrays.stream(originLabels.split(",")).collect(Collectors.toSet());
            oldLabels.addAll(Arrays.stream(labels.split(",")).collect(Collectors.toSet()));
            liveInfo.setLabels(String.join(",", oldLabels));
        } else {
            liveInfo.setLabels(labels);
            if (Strings.isNotBlank(matchId)) {
                liveInfo.setMatchId(matchId);
                liveInfo.setLeague(dbService.fetchCnd(CrownMatch.class, Cnd.where("id", "=", matchId)).getLeague());
            }
        }
        redisService.hset(KEY_LIVE, key, JSONUtil.toJSONString(liveInfo));
    }


    @Override
    public Object liveMember(String liveNo) {
        Set<String> channelIds = redisService.hgetAll(ChatConstant.CHAT_ROOM + liveNo).keySet();
        return redisService.hgetAll(ChatConstant.CHAT_USER).values()
                .stream().map(JSONObject::parse).filter(jsonObj -> {
                    JSONObject json = (JSONObject) jsonObj;
                    return channelIds.contains(json.get("channelId"));
                }).
                        collect(Collectors.toList());
    }


    @Override
    public void cover(String liveNo, String format) {
        HttpServletResponse response = Mvcs.getResp();
        switch (format) {
            case "base64": {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                Result.response(response, Result.HTTP_STATUS.OK, null,
                        Result.success(
                                redisService.hget("liveOutPic", liveNo)
                        ));
                break;
            }
            default: {
                response.setDateHeader("Expires", 0L);
                response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
                response.addHeader("Cache-Control", "post-check=0, pre-check=0");
                response.setHeader("Pragma", "no-cache");
                response.setContentType("image/jpeg");
                try {
                    Result.response(response, Result.HTTP_STATUS.OK, null,
                            new BASE64Decoder().decodeBuffer(
                                    redisService.hget("liveOutPic", liveNo)
                            )
                    );
                } catch (IOException e) {
                    log.error(e.getMessage());
                }

            }
        }

    }

    private LiveInfo parseToLiveInfo(String str) {
        return JSONObject.parseObject(str, LiveInfo.class);
    }


    /**
     * 刷新直播信息并清除无效数据、文件
     */
    @Override
    public void refreshLive() {
        // 官方账号
        User user = userService.fetch(Cnd.where(PHONE, "=", PHONE_NUM));
        //直播数据
        Map<String, String> stringStringMap = redisService.hgetAll(RedisKey.KEY_LIVE);

        for (Map.Entry<String, String> entry : stringStringMap.entrySet()) {
            String keyStr = entry.getKey();
            String valStr = entry.getValue();
            MatchVO data = JSONUtil.parseStringToJavaBean(MatchVO.class, valStr);
            //region 清理官方直播数据
            if (keyStr.startsWith(user.getId())) {
                String videoId = keyStr.replace(user.getId() + _AND_, "");
                String matchInfo = redisService.hget(RedisKey.KEY_MATCH, videoId);
                //清空已过期赛事的官方账户直播数据
                if (Strings.isEmpty(matchInfo)) {
                    redisService.hdel(RedisKey.KEY_LIVE, keyStr);
                    ImageUtil.removeFile(conf.get(JETTY_STATIC_PATH, UPLOAD) + _LIVE_ + keyStr + PNG_SUFFIX);
                }
                //region 清理截取不到图片的数据
                else if (!VideoUtil.fetchFrame(data.getStreamUrl(), conf.get(JETTY_STATIC_PATH, UPLOAD) + _LIVE_ + keyStr + PNG_SUFFIX)) {
                    redisService.hdel(RedisKey.KEY_LIVE, keyStr);
                    ImageUtil.removeFile(conf.get(JETTY_STATIC_PATH, UPLOAD) + _LIVE_ + keyStr + PNG_SUFFIX);
                }
            }
            //endregion
            //region 非官方直播数据刷新封面图
            else {
                // 刷新封面图
                String imgUrl = _LIVE_ + keyStr + PNG_SUFFIX;
                boolean fetchFrame = VideoUtil.fetchFrame(data.getStreamUrl(), conf.get(JETTY_STATIC_PATH, UPLOAD) + imgUrl);
                if (fetchFrame) {
                    redisService.hset(Fields.LIVE_COVER_PIC, keyStr, "/file" + imgUrl);
                }
            }
            //endregion
        }
        //region 清理图片
        Set<String> living = stringStringMap.keySet();
        String imgBasePath = conf.get(JETTY_STATIC_PATH, UPLOAD) + _LIVE_;
        File dir = new File(imgBasePath);
        File[] files = dir.listFiles();
        if (files != null) {
            for (File file : files) {
                String liveNo = file.getName().replace(PNG_SUFFIX, "");
                if (!living.contains(liveNo)) {
                    file.delete();
                }
            }
        }
        //endregion
    }

}
